---
title: Collaboration
status: published
author: alex
date: 7/24/2024
order: 6
keywords:
  - data
  - sync
  - persistence
  - database
  - multiplayer
  - collaboration
  - server
  - websockets
---

The tldraw SDK includes deep support for real-time collaboration. The easiest way to add collaboration to your project is with our [tldraw sync](#tldraw-sync) library. Or you can use our low-level data APIs to integrate [other backends](#Using-other-collaboration-backends).

<div className="article__image" style={{ border: 'none' }}>
	<img
		alt="Multiplayer example using tldraw sync"
		src="/images/multiplayer.gif"
		style={{
			// learn this one weird trick for transparent animated gifs. doctors hate her!!!
			mask: 'url(/images/multiplayer_mask.png) luminance center 100% / 100% no-repeat',
			WebkitMask: 'url(/images/multiplayer_mask.png) luminance center 100% / 100% no-repeat',
		}}
	/>
</div>

## tldraw sync

[tldraw sync](/docs/sync) is our library for fast multi-user collaboration. It's purpose-built for the tldraw canvas and it's what we use to power collaboration on our flagship app tldraw.com.

You can read our full article on [tldraw sync](/docs/sync).

### tldraw sync demo

To make it easier to get started with collaboration in tldraw, we've included a "demo" hook in the sync library that connects to a hosted backend. You can see a working example at [this example](https://tldraw.dev/examples/sync-demo).

Let's say you have an app running locally that looks like this:

```tsx
import { Tldraw } from 'tldraw'

function MyApp() {
	return <Tldraw />
}
```

To make this app collaborative, first install the `@tldraw/sync` library:

```bash
npm install @tldraw/sync
```

Back in your code, import the `useSyncDemo` hook from the `@tldraw/sync` library. In the `MyApp` component, call the `useSyncDemo` hook with a room ID. Pass the [`store`](/docs/persistence#The-store-prop) returned by `useSyncDemo` to the tldraw component's `store` prop.

```tsx
import { Tldraw } from 'tldraw'
import { useSyncDemo } from '@tldraw/sync'

function MyApp() {
	const store = useSyncDemo({ roomId: 'my-unique-room-id' })
	return <Tldraw store={store} />
}
```

In your browser, open an incognito window and visit your project's URL. You can also use a different browser or different device. The key is the room ID: any apps connecting to the same room ID will enter into a shared collaboration session.

### Limitations of the demo

The sync demo is great for prototyping but you should not use it in production. Data on the demo server only lasts for up to 24 hours, and anyone using the same room id will be able to edit the same room's project.

### Using tldraw sync in production

To use tldraw sync in production, you will need to self-host the tldraw sync server. To learn more, see our article on [tldraw sync](/docs/sync).

> We don't offer a hosted solution for tldraw sync in production, but if you're interested in that please let us know at hello@tldraw.com.

## Using other collaboration backends

While [tldraw sync](/docs/sync) is our recommended and best-supported backend for tldraw, we designed the tldraw SDK to work with any data solution. For example, Liveblocks offers a [tldraw starter](https://liveblocks.io/examples/tldraw-whiteboard), and many product teams have plugged tldraw into their own real-time data solutions.

### Manual setup

Collaboration in tldraw involves synchronizing data, sharing user presence, and handling user assets.

#### Synchronizing data

For more information about how to synchronize the tldraw editor's store with other processes—how to get data out and put data in, including from remote sources—see the [Persistence](/docs/persistence) page.

#### User presence

The tldraw SDK has support for displaying the 'presence' of other users. Presence information consists of the user id, name, and color, as well as their canvas context, such as their current page, pointer position, selection, viewport.

A user's presence is stored as `instance_presence` ([TLInstancePresence](?))records in the editor's store, however the data itself may be derived from other sources.

We provide a helper, [createPresenceStateDerivation](?), for constructing a reactive signal for an `instance_presence` record locally, which can then be sent to other clients somehow.

To the editor, any `instance_presence` records that belong to other users (i.e. those with a different user id than the editor's configured user id) are considered "collaborators". The editor has two methods, `getCollaborators` and `getCollaboratorsOnCurrentPage`, which return reactive signals about the current collaborators.

#### Collaboration UI

The `tldraw` library includes several components specifically designed for collaboration.
You can remove, replace, or customize these using the editor's `components` prop. See [TLComponents](?) for more info.

- Collaborator cursors: [`TLComponents#CollaboratorCursor`](?)
- Cursor chat: [`TLComponents#CursorChatBubble`](?)
- Offline indicator: [`TLComponents#TopPanel`](?)
- Collaborator list: [`TLComponents#SharePanel`](?)
